package org.spiderflow.common.redis.userinfo;

import org.apache.commons.lang3.StringUtils;
import org.spiderflow.config.GlobalErrorInfoEnum;
import org.spiderflow.config.exception.ExecptionWhole;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spiderflow.config.permission.PermissionCodeEnum;
import org.spiderflow.permission.entity.SysUserPermisson;
import org.spiderflow.users.entity.Users;
import org.spiderflow.users.entity.UsersPermission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Set;

/**
 * @Author: tjs
 * @Date: 2019/5/20 17:54
 * @Desc:
 */
@Component
public class RedisUserInfoUtil {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private HttpServletRequest thisRequest;


    private static Logger logger = LoggerFactory.getLogger(RedisUserInfoUtil.class);

    private static final String usersOps = "sisi_crawler";
    private static final String AuthorizationStr = "Authorization";

    public void logout() {
        String key = thisRequest.getHeader(AuthorizationStr);
        if (key != null) {
            Set<String> keys = redisTemplate.keys(key + ":*");
            redisTemplate.delete(keys);
            redisTemplate.opsForValue().getOperations().delete(redisTemplate.keys(key + ":*"));

        } else {
            throw new ExecptionWhole(GlobalErrorInfoEnum.USER_NO_KEY);
        }
    }

    public void initUserInfo(Users userInfo) {
        //模糊查找，删除所有的key
        String key = "Users_" + userInfo.getUserPhone();
        Set<String> keys = redisTemplate.keys(key + ":*");
        redisTemplate.delete(keys);
        redisTemplate.opsForValue().getOperations().delete(redisTemplate.keys(key + ":*"));
        //新增用户缓存信息
        redisTemplate.boundHashOps(usersOps)
                .put(key, userInfo);
    }


    /**
     * 获取当前登录用户
     *
     * @return
     * @throws Exception
     */
    public Users getUserByKey() throws Exception {
        Users user = null;
        String key = thisRequest.getHeader(AuthorizationStr);
        if (key != null) {
            Object userObject = redisTemplate.boundHashOps(usersOps)
                    .get(key);
            if (userObject != null) {
                user = (Users) userObject;
            }
        }
        if (user == null) {
            throw new ExecptionWhole(GlobalErrorInfoEnum.USER_NO_LOGIN);
        }
        return user;
    }

    /**
     * 检查是否有权限
     *
     * @param permissionCodeEnum
     * @throws Exception
     */
    public void checkPer(Users user, PermissionCodeEnum permissionCodeEnum) throws Exception {
        //减少访问redis的次数
        if(permissionCodeEnum.getCode()==null){
            return;
        }
        if (user == null) {
            user = getUserByKey();
        }
        if (CollectionUtils.isEmpty(user.getPermissions())) {
            throw new ExecptionWhole(permissionCodeEnum);
        }
        for (UsersPermission usersPermission : user.getPermissions()) {
            if (permissionCodeEnum.getCode().equals(usersPermission.getPerCode())) {
                return;
            }
        }
        throw new ExecptionWhole(permissionCodeEnum);
    }

    public void checkPer(PermissionCodeEnum permissionCodeEnum) throws Exception {
        if(permissionCodeEnum.getCode()==null){
            return;
        }
        checkPer(getUserByKey(), permissionCodeEnum);
    }
    public boolean checkPer(Users user, PermissionCodeEnum permissionCodeEnum, Integer perScope) throws Exception {
        //减少访问redis的次数
        if(permissionCodeEnum.getCode()==null){
            return true;
        }
        if (user == null) {
            user = getUserByKey();
        }
        if (CollectionUtils.isEmpty(user.getPermissions())) {
            return false;
        }
        for (UsersPermission usersPermission : user.getPermissions()) {
            if (permissionCodeEnum.getCode().equals(usersPermission.getPerCode()) && perScope != null && perScope.equals(usersPermission.getPerScope())) {
                return true;
            }
        }
        return false;
    }
    public boolean checkPerOfAll(PermissionCodeEnum permissionCodeEnum) throws Exception {
        return this.checkPer(getUserByKey(),permissionCodeEnum, SysUserPermisson.Constant.PerScope.all);
    }
    public boolean checkPerOfAll(Users user, PermissionCodeEnum permissionCodeEnum) throws Exception {
        return this.checkPer(user,permissionCodeEnum, SysUserPermisson.Constant.PerScope.all);
    }
}
